home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / viewers / mpgsrcpl.lha / org20 / 2x2.c < prev    next >
C/C++ Source or Header  |  2001-02-02  |  9KB  |  377 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. #include "video.h"
  23. #include "dither.h"
  24. #include "proto.h"
  25.  
  26. #define RAND_ERR_RANGE 7
  27. #define RAND_ERR_SUBVAL 3
  28.  
  29. /* Array containing actual pixel values for each possible 2x2 dither pattern. */
  30.  
  31. static unsigned char *dith_a;
  32.  
  33. /* Arrays mapping lum, cr, and cb values to portions of dither pattern code. 
  34.    The addtion of one value from each array yields a valid dither pattern
  35.    code.
  36. */
  37.  
  38. static int lval_a[256+RAND_ERR_RANGE-1];
  39. static int rval_a[256+RAND_ERR_RANGE-1];
  40. static int bval_a[256+RAND_ERR_RANGE-1];
  41.  
  42. /* Range of possible dither patterns in each channel. */
  43.  
  44. #define L_DITH_RANGE (((LUM_RANGE-1)*4)+1)
  45. #define CR_DITH_RANGE (((CR_RANGE-1)*4)+1)
  46. #define CB_DITH_RANGE (((CB_RANGE-1)*4)+1)
  47.  
  48. /* Arrays of random error terms added to break up contours. */
  49.  
  50. static int *randval_a;
  51. static int **randptr_a;
  52.  
  53.  
  54. /*
  55.  *--------------------------------------------------------------
  56.  *
  57.  *  Init2x2Dither--
  58.  *
  59.  *    Initializes structures used for 2x2 dithering.
  60.  *
  61.  * Results:
  62.  *    None.
  63.  *
  64.  * Side effects:
  65.  *    None.
  66.  *
  67.  *--------------------------------------------------------------
  68.  */
  69.  
  70. void
  71. Init2x2Dither()
  72. {  
  73.   unsigned char *dith_ca;
  74.   int numcodes;
  75.   int l_range, cr_range, cb_range;
  76.   int p1, p2, p3, p4;
  77.   int l_dith, cr_dith, cb_dith;
  78.   int big_part, small_part;
  79.   int i, j;
  80.  
  81.   l_range = L_DITH_RANGE;
  82.   cr_range = CR_DITH_RANGE;
  83.   cb_range = CB_DITH_RANGE;
  84.  
  85.   numcodes =  l_range * cr_range * cb_range;
  86.  
  87.   dith_a = (unsigned char *) malloc(numcodes*4);
  88.  
  89.   dith_ca =  dith_a;
  90.  
  91.   for (i=0; i<numcodes; i++) {
  92.     l_dith = i  % l_range;
  93.  
  94.     big_part = l_dith / 4;
  95.     small_part = l_dith % 4;
  96.  
  97.     p1 = big_part + ((small_part > 0) ? 1 : 0);
  98.     p2 = big_part + ((small_part > 2) ? 1 : 0);
  99.     p3 = big_part;
  100.     p4 = big_part + ((small_part > 1) ? 1 : 0);
  101.  
  102.     p1 *= CR_RANGE * CB_RANGE;
  103.     p2 *= CR_RANGE * CB_RANGE;
  104.     p3 *= CR_RANGE * CB_RANGE;
  105.     p4 *= CR_RANGE * CB_RANGE;
  106.  
  107.     cr_dith = (i/l_range) % cr_range;
  108.  
  109.     big_part = cr_dith / 4;
  110.     small_part = cr_dith % 4;
  111.  
  112.     p1 += (big_part + ((small_part > 0) ? 1 : 0))*CB_RANGE;
  113.     p2 += (big_part + ((small_part > 2) ? 1 : 0))*CB_RANGE;
  114.     p3 += (big_part)*CB_RANGE;
  115.     p4 += (big_part + ((small_part > 1) ? 1 : 0))*CB_RANGE;
  116.  
  117.     cb_dith = (i/(cr_range*l_range)) % cb_range;
  118.  
  119.     big_part = cb_dith / 4;
  120.     small_part = cb_dith % 4;
  121.  
  122.     p1 += (big_part + ((small_part > 0) ? 1 : 0));
  123.     p2 += (big_part + ((small_part > 2) ? 1 : 0));
  124.     p3 += (big_part);
  125.     p4 += (big_part + ((small_part > 1) ? 1 : 0));
  126.  
  127.     *dith_ca++ = p1;
  128.     *dith_ca++ = p2;
  129.     *dith_ca++ = p3;
  130.     *dith_ca++ = p4;
  131.   }
  132.  
  133.   for (i=RAND_ERR_SUBVAL; i<256+RAND_ERR_SUBVAL; i++) {
  134.     j = i-RAND_ERR_SUBVAL;
  135.     lval_a[i] = (j * L_DITH_RANGE)/256;
  136.     rval_a[i] = (j * CR_DITH_RANGE)/256;
  137.     bval_a[i] = (j * CB_DITH_RANGE)/256;
  138.  
  139.     bval_a[i] *= CR_DITH_RANGE * L_DITH_RANGE * 4;
  140.     rval_a[i] *= L_DITH_RANGE * 4;
  141.     lval_a[i] *= 4;
  142.   }
  143.  
  144.   for (i=0; i<RAND_ERR_SUBVAL; i++) {
  145.     lval_a[i] = lval_a[RAND_ERR_SUBVAL];
  146.     rval_a[i] = rval_a[RAND_ERR_SUBVAL];
  147.     bval_a[i] = bval_a[RAND_ERR_SUBVAL];
  148.   }
  149.  
  150.    for(i=256+RAND_ERR_SUBVAL; i<256+RAND_ERR_RANGE-1; i++) {
  151.      lval_a[i] = lval_a[255+RAND_ERR_SUBVAL];
  152.      rval_a[i] = rval_a[255+RAND_ERR_SUBVAL];
  153.      bval_a[i] = bval_a[255+RAND_ERR_SUBVAL];
  154.    }
  155. }
  156.  
  157.  
  158. /*
  159.  *--------------------------------------------------------------
  160.  *
  161.  * RandInit --
  162.  *
  163.  *    Initializes the random values used for 2x2 dithering.
  164.  *
  165.  * Results:
  166.  *    randval_a filled with random values.
  167.  *      randptr_a filled with random pointers to random value arrays.
  168.  *
  169.  * Side effects:
  170.  *      None.
  171.  *
  172.  *--------------------------------------------------------------
  173.  */
  174.  
  175. void RandInit(h, w)
  176.      int h, w;
  177. {
  178.   int i;
  179.  
  180.   randval_a = (int *) malloc(w*5*sizeof(int));
  181.   randptr_a = (int **) malloc(h*sizeof(int *));
  182.  
  183. #ifdef NO_LRAND48
  184.   for (i=0; i<w*5; i++) {
  185.     long int random();
  186.  
  187.     randval_a[i] = random() % RAND_ERR_RANGE;
  188.   }
  189.  
  190.   for (i=0; i<h; i++) {
  191.     long int random();
  192.  
  193.     randptr_a[i] = randval_a + (random() % (w*2));
  194.   }
  195. #else /* NO_LRAND48 */
  196.  
  197.   for (i=0; i<w*5; i++) {
  198.     long int lrand48();
  199.     
  200.     randval_a[i] = lrand48() % RAND_ERR_RANGE;
  201.   }
  202.   
  203.   for (i=0; i<h; i++) {
  204.     long int lrand48();
  205.  
  206.     randptr_a[i] = randval_a + (lrand48() % (w*2));
  207.   }
  208. #endif
  209.   
  210. }
  211.  
  212.  
  213. /*
  214.  *--------------------------------------------------------------
  215.  *
  216.  *  PostInit2x2Dither--
  217.  *
  218.  *    Remaps color numbers in dither patterns to actual pixel
  219.  *      values allocated by the X server.
  220.  *
  221.  * Results:
  222.  *      None.
  223.  *
  224.  * Side effects:
  225.  *      None.
  226.  *
  227.  *--------------------------------------------------------------
  228.  */
  229.  
  230. void
  231. PostInit2x2Dither() 
  232. {
  233.   unsigned char *dith_ca;
  234.   int i;
  235.  
  236.   dith_ca = dith_a;
  237.  
  238.   for (i=0; i < (L_DITH_RANGE * CR_DITH_RANGE * CB_DITH_RANGE); i++) {
  239.     
  240.     *dith_ca = pixel[*dith_ca];
  241.     dith_ca++;
  242.     *dith_ca = pixel[*dith_ca];
  243.     dith_ca++;
  244.     *dith_ca = pixel[*dith_ca];
  245.     dith_ca++;
  246.     *dith_ca = pixel[*dith_ca];
  247.     dith_ca++;
  248.   }
  249. }
  250.  
  251.  
  252. /*
  253.  *--------------------------------------------------------------
  254.  *
  255.  * Twox2DitherImage --
  256.  *
  257.  *    Dithers lum, cr, and cb channels togethor using predefined
  258.  *      and computed 2x2 dither patterns. Each possible combination of
  259.  *      lum, cr, and cb values combines to point to a particular dither
  260.  *      pattern (2x2) which is used to represent the pixel. This assumes
  261.  *      That the display plane is 4 times larger than the lumianance 
  262.  *      plane. 
  263.  *
  264.  * Results:
  265.  *      None.
  266.  *
  267.  * Side effects:
  268.  *      None.
  269.  *
  270.  *--------------------------------------------------------------
  271.  */
  272.  
  273. void 
  274. Twox2DitherImage(lum, cr, cb, out, h, w)
  275.     unsigned char *lum;
  276.     unsigned char *cr;
  277.     unsigned char *cb;
  278.     unsigned char *out;
  279.     int w, h;
  280. {
  281.   int i, j;
  282.   unsigned short *o1, *o2, *o3, *o4;
  283.   unsigned char *l1, *l2, *base;
  284.   unsigned char B, R;
  285.   unsigned short *dith_ca;
  286.   int big_adv = 3*w;
  287.   int b_val, r_val, l_val;
  288.   int *randvalptr;
  289.   int randval;
  290.   static int first = 1;
  291.  
  292.   if (first) {
  293.     RandInit(h, w);
  294.     first = 0;
  295.   }
  296.  
  297.   o1 = (unsigned short *)out;
  298.   o2 = (unsigned short *)(out+(2*w));
  299.   o3 = (unsigned short *)(out+(4*w));
  300.   o4 = (unsigned short *)(out+(6*w));
  301.   l1 = lum;
  302.   l2 = lum+w;
  303.  
  304.   for (i=0; i<h; i+=2) {
  305.     for(j=0; j<w; j+= 4) {
  306.  
  307.       B = cb[0];
  308.       b_val = bval_a[B];
  309.       R = cr[0];
  310.       r_val = rval_a[R];
  311.       base = dith_a + b_val + r_val;
  312.  
  313.       l_val = lval_a[l1[0]];
  314.       dith_ca = (unsigned short *)(base + l_val);
  315.       o1[0] = dith_ca[0];
  316.       o2[0] = dith_ca[1];
  317.  
  318.       l_val = lval_a[l1[1]];
  319.       dith_ca = (unsigned short *)(base + l_val);
  320.       o1[1] = dith_ca[0];
  321.       o2[1] = dith_ca[1];
  322.  
  323.       l_val = lval_a[l2[0]];
  324.       dith_ca = (unsigned short *)(base + l_val);
  325.       o3[0] = dith_ca[0];
  326.       o4[0] = dith_ca[1];
  327.  
  328.       l_val = lval_a[l2[1]];
  329.       dith_ca = (unsigned short *)(base + l_val);
  330.       o3[1] = dith_ca[0];
  331.       o4[1] = dith_ca[1];
  332.  
  333.       B = cb[1];
  334.       b_val = bval_a[B];
  335.       R = cr[1];
  336.       r_val = rval_a[R];
  337.       base = dith_a + b_val + r_val;
  338.  
  339.       l_val = lval_a[l1[2]];
  340.       dith_ca = (unsigned short *)(base + l_val);
  341.       o1[2] = dith_ca[0];
  342.       o2[2] = dith_ca[1];
  343.  
  344.       l_val = lval_a[l1[3]];
  345.       dith_ca = (unsigned short *)(base + l_val);
  346.       o1[3] = dith_ca[0];
  347.       o2[3] = dith_ca[1];
  348.  
  349.       l_val = lval_a[l2[2]];
  350.       dith_ca = (unsigned short *)(base + l_val);
  351.       o3[2] = dith_ca[0];
  352.       o4[2] = dith_ca[1];
  353.  
  354.       l_val = lval_a[l2[3]];
  355.       dith_ca = (unsigned short *)(base + l_val);
  356.       o3[3] = dith_ca[0];
  357.       o4[3] = dith_ca[1];
  358.  
  359.       o1 += 4;
  360.       o2 += 4;
  361.       o3 += 4;
  362.       o4 += 4;
  363.       l1 += 4;
  364.       l2 += 4;
  365.       cb += 2;
  366.       cr += 2;
  367.     }    
  368.  
  369.     l1 += w;
  370.     l2 += w;
  371.     o1 += big_adv;
  372.     o2 += big_adv;
  373.     o3 += big_adv;
  374.     o4 += big_adv;
  375.   }
  376. }
  377.